package com.shuogesha.app.action;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.util.AlipayUtils;
import com.shuogesha.app.version.AccessTokenRequired;
import com.shuogesha.app.web.util.ApiUtils;
import com.shuogesha.cms.entity.Address;
import com.shuogesha.cms.entity.Cart;
import com.shuogesha.cms.entity.Order;
import com.shuogesha.cms.entity.Product;
import com.shuogesha.cms.entity.ProductAttr;
import com.shuogesha.cms.service.AddressService;
import com.shuogesha.cms.service.CartService;
import com.shuogesha.cms.service.OrderService;
import com.shuogesha.cms.service.ProductAttrService;
import com.shuogesha.cms.service.ProductService;
import com.shuogesha.common.util.BigDecimalArith;
import com.shuogesha.common.util.JsonResult;
import com.shuogesha.common.util.ResultCode;
import com.shuogesha.common.util.UtilDate;
import com.shuogesha.platform.entity.Account;
import com.shuogesha.platform.entity.Paybill;
import com.shuogesha.platform.entity.Paylog;
import com.shuogesha.platform.entity.Payments;
import com.shuogesha.platform.entity.UnifiedUser;
import com.shuogesha.platform.service.AccountService;
import com.shuogesha.platform.service.PaybillService;
import com.shuogesha.platform.service.PaylogService;
import com.shuogesha.platform.service.PaymentsService;
import com.shuogesha.platform.web.mongo.Pagination;
import com.shuogesha.platform.web.util.RequestUtils;
import com.wechat.oauth.WxSign;
import com.wechat.util.ConfKit;
/**
 * 下单
 * @author zhaohaiyuan
 *
 */
@Controller
@RequestMapping("/app/")
public class ApiOrderAct {
	private static Logger log = LoggerFactory.getLogger(ApiOrderAct.class);
	/**
	 * 下单临时存储
	 * @param str
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "create_order", method = RequestMethod.POST)
 	@AccessTokenRequired
	public @ResponseBody Object create_order(@RequestBody String str,HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		JSONObject json = JSONObject.parseObject(str); 
		List<Cart> list =new JSONArray().parseArray(json.getString("goodsData"), Cart.class); 
		List<Cart> allList= new ArrayList<>();//下单的商品
		BigDecimal total=BigDecimal.ZERO;//总金额
		for (Cart cart : list) {
			//商品的购物
			if(Product.class.getSimpleName().equals(cart.getRefer())){
				Product product=productService.findById(cart.getReferid());
				if(product==null) {
					return new JsonResult(ResultCode.FAIL, "商品不存在",null);
				}
				cart.setName(product.getName()); 
				BigDecimal price=product.getPrice();
				if(cart.getAttrId()!=null&&cart.getAttrId()>0) {
					ProductAttr productAttr=productAttrService.findById(cart.getAttrId());
					if(productAttr==null) {
						return new JsonResult(ResultCode.FAIL, "商品已经下架",null);
					}
					if(productAttr.getPrice()!=null&&productAttr.getPrice().compareTo(BigDecimal.ZERO)>0) {
						price=productAttr.getPrice();
					}
					cart.setRemark(productAttr.getAttributes());
				}
				cart.setPrice(price);
				cart.setImg(product.getImg()); 
				//重新计算一下价格
				BigDecimal total1=BigDecimalArith.mul(price,BigDecimal.valueOf(cart.getNum()));
				total=BigDecimalArith.add(total1, total);
				allList.add(cart);
			} 
		}
		if(allList==null||allList.size()<=0) {
			return new JsonResult(ResultCode.FAIL, "参数错误",null);
		}
		JSONObject order=new JSONObject();
		String orderNo=UtilDate.getOrderNum();
		order.put("orderNo", orderNo);
		order.put("total", total);
		order.put("goodsData", allList);
		strRedisTemplate.opsForValue().set("CreateOrder_"+orderNo,order.toString(),10,TimeUnit.MINUTES);//10分钟以后过期  
		return new JsonResult(ResultCode.SUCCESS, order);
	}
	/**
	 * 获取临时订单
	 * @param orderNo
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "get_create_order")
 	@AccessTokenRequired
	public @ResponseBody Object get_create_order(String orderNo,HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		if(StringUtils.isBlank(orderNo)) {
			return new JsonResult(ResultCode.FAIL, "参数错误",null);
		} 
		String order=strRedisTemplate.opsForValue().get("CreateOrder_"+orderNo);
		if(StringUtils.isBlank(order)) {
			return new JsonResult(ResultCode.FAIL, "参数错误",null);
		}
		JSONObject orderInfo=(JSONObject) JSON.parse(order);
		Address address=addressService.findByDefault(ApiUtils.getUnifiedUserId(request));
		orderInfo.put("addressData", address);
		return new JsonResult(ResultCode.SUCCESS,orderInfo);
	}
	/**
	 * 商品下单操作
	 * @param str
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "save_order", method = RequestMethod.POST)
 	@AccessTokenRequired
	public @ResponseBody Object save_order(@RequestBody String str,HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		if(StringUtils.isBlank(str)) {
			return new JsonResult(ResultCode.FAIL, "参数错误",null);
		} 
 		Order bean= JSON.parseObject(str, Order.class); //转order 
 		JSONObject json = JSONObject.parseObject(str); //必须带产品和收货地址
 		if(StringUtils.isBlank(json.getString("goodsData"))) {
 			return new JsonResult(ResultCode.FAIL, "参数错误",null);
 		} 
		List<Cart> list =new JSONArray().parseArray(json.getString("goodsData"), Cart.class); 
		List<Cart> allList= new ArrayList<>();//下单的商品
		BigDecimal total=BigDecimal.ZERO;//总金额
		Integer num=0;//总数量 
		for (Cart cart : list) {
			//商品的购物
			if(Product.class.getSimpleName().equals(cart.getRefer())){
				Product product=productService.findById(cart.getReferid());
				if(product==null) {
					return new JsonResult(ResultCode.FAIL, "商品不存在",null);
				}
				cart.setName(product.getName());
				BigDecimal price=product.getPrice();
				if(cart.getAttrId()!=null&&cart.getAttrId()>0) {
					ProductAttr productAttr=productAttrService.findById(cart.getAttrId());
					if(productAttr==null) {
						return new JsonResult(ResultCode.FAIL, "商品已经下架",null);
					}
					if(productAttr.getPrice()!=null&&productAttr.getPrice().compareTo(BigDecimal.ZERO)>0) {
						price=productAttr.getPrice();
					}
					cart.setRemark(productAttr.getAttributes());
				}
 				cart.setPrice(price);
				cart.setImg(product.getImg());  
				//重新计算一下价格
				//重新计算一下价格
				BigDecimal total1=BigDecimalArith.mul(price,BigDecimal.valueOf(cart.getNum()));
				total=BigDecimalArith.add(total1, total);
				num=num+Integer.valueOf(cart.getNum()).intValue();
				allList.add(cart);
			} 
		}
		if(allList==null||allList.size()<=0) {
			return new JsonResult(ResultCode.FAIL, "参数错误",null);
		}
		Address address = JSON.parseObject(json.getString("addressData"), Address.class); //转order 
		JSONObject order=new JSONObject();
		String orderNo=UtilDate.getOrderNum();
  		order.put("goodsData", allList);
  		if(address!=null) {
  			order.put("addressData", address);
  			bean.setPhone(address.getPhone());
  			bean.setAddress(address.getAddress());
  		}
  		bean.setOrderNo(orderNo);
		bean.setContent(order.toJSONString());
		bean.setNum(num);
		bean.setPrice(total);
		bean.setTotal(total);
		bean.setDateline(UtilDate.getNow());
		bean.setOrderNo(UtilDate.getOrderNum());
		bean.setUnifiedUser(ApiUtils.getUnifiedUser(request));
		orderService.save(bean);
		//删除购物车
		for (Cart cart : list) {
			if(cart.getId()!=null&&cart.getId()>0) {
				cartService.removeById(cart.getId());
			} 
		} 
		//清空缓存 
		strRedisTemplate.delete("CreateOrder_"+json.get("orderNo"));
 		return new JsonResult(ResultCode.SUCCESS,bean);
	}
	/**
	 * 获取支付方式
	 * @param orderNo
	 * @param platform
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "get_payments")
 	@AccessTokenRequired
	public @ResponseBody Object get_payments(String orderNo,String platform, HttpServletRequest request,
			HttpServletResponse response, ModelMap model) throws Exception {
  		if(StringUtils.isBlank(orderNo)){
			return new JsonResult(ResultCode.FAIL,"参数错误",null);
		}
		Order bean = orderService.findByOrderNo(orderNo);
		if(bean==null||!ApiUtils.getUnifiedUserId(request).equals(bean.getUnifiedUser().getId())){
			return new JsonResult(ResultCode.FAIL,"订单不存在",null);
		}
		List<Payments> list= paymentsService.findList(platform);
		JSONObject order=new JSONObject();
		order.put("order", bean);
		order.put("payments", list);
		order.put("account", accountService.init(ApiUtils.getUnifiedUserId(request)));
		return new JsonResult(ResultCode.SUCCESS,order);
	}
	/**
	 * 订单支付
	 * @param id
	 * @param payType
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "pay_order", method = RequestMethod.POST)
 	@AccessTokenRequired
	public @ResponseBody Object pay_order(@RequestBody Order order, HttpServletRequest request,
			HttpServletResponse response, ModelMap model) throws Exception {
   		if(StringUtils.isBlank(order.getPayType())||order.getId()==null||order.getId()<=0){
			return new JsonResult(ResultCode.FAIL,"参数错误",null);
		}
		Order bean = orderService.findById(order.getId());
		if(bean==null||!Order.PAY_WEIZHIFU.equals(bean.getPay())){//余额支付
			return new JsonResult(ResultCode.FAIL,"订单异常",null);
		}
		if(Paybill.PAYTYPE_YUE.equals(order.getPayType())){//余额支付
			Account account = accountService.findById(ApiUtils.getUnifiedUserId(request));
			if(account.getAccount().compareTo(bean.getPrice())<0){ 
				return new JsonResult(ResultCode.FAIL,"余额不足",null);
			}
		}
		
		bean.setPayType(order.getPayType());
		orderService.update(bean);
		UnifiedUser unifiedUser=ApiUtils.getUnifiedUser(request);
		String subject = "用户订单_"+bean.getOrderNo();
		String body = "用户订单";  
		String type=Paybill.ORDER;
		if(Order.SERVICE.equals(bean.getName())){
			 type=Paybill.SERVICE;
		}
		Paybill payBill =  new Paybill(type,bean.getOrderNo(),subject,body,order.getPayType(), bean.getPrice(),unifiedUser.getId(),unifiedUser.getUsername());
		paybillService.save(payBill);
		Paylog payLog = payLogService.create(payBill.getId(),type,"0");
		Map<String, Object> re = new HashMap<String, Object>(); 
		re.put("paybill", paybillService.findById(payBill.getId()));
		if(Paybill.PAYTYPE_YUE.equals(order.getPayType())){//余额支付 
			paybillService.pay(payLog, 1,true);  
			return new JsonResult(ResultCode.SUCCESS,"支付成功",re);
		}
		if("alipay".equals(order.getPayType())&&"app".equals(order.getPlatform())){
			String data=AlipayUtils.pay_app(payBill.getId(), bean.getPrice().toString(), subject, body, "");
			re.put("data", data);
			return new JsonResult(ResultCode.SUCCESS,"",re);
		}else if("alipay".equals(order.getPayType())&&"pc".equals(order.getPlatform())){
			String data=AlipayUtils.pay_now(payBill.getId(), bean.getPrice().toString(), subject, body, "");
			re.put("data", data);
			return new JsonResult(ResultCode.SUCCESS,"",re);
		}else if("wechat".equals(order.getPayType())){
 			SortedMap<String, Object> params = new TreeMap<String,Object>();
			String appId = ConfKit.get("AppId");
		    String partnerId = ConfKit.get("partnerId");
		    String partnerKey = ConfKit.get("partnerKey");
		    String notify_url = ConfKit.get("notify_url");
		    String nonce_str=WxSign.getNonceStr();
		    params.put("appid", appId);
		    params.put("mch_id", partnerId);
		    params.put("nonce_str",nonce_str);
		    params.put("device_info", "APP");
		    params.put("body", payBill.getSubject());
		    params.put("out_trade_no", payBill.getId());
		    Double priceDouble= payBill.getTranAmount().doubleValue(); //微信的需要变换成分
		    priceDouble=priceDouble*100;
		    params.put("total_fee", String.valueOf(priceDouble.intValue())); 
		    params.put("spbill_create_ip", RequestUtils.getIpAddr(request)); 
		    params.put("notify_url", notify_url);
		    params.put("trade_type", "APP");
	        //附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
		    params.put("attach", "");
		    String sign= WxSign.createSign(params,partnerKey);
		    params.put("sign", sign); 
		    String requestXML = WxSign.getRequestXml(params);
			System.out.println(requestXML);
			String result = WxSign.httpsRequest(
					"https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",
					requestXML);
			System.out.println(result);
 			try {
 				Map<String, Object> map1=WxSign.doXMLParse(result); 
 				SortedMap<String, Object> payMap = new TreeMap<String,Object>();
				payMap.put("appid", appId);
				 payMap.put("partnerid", partnerId);
				 payMap.put("prepayid", map1.get("prepay_id"));
				 payMap.put("package", "Sign=WXPay");
				 payMap.put("noncestr", nonce_str);
				 payMap.put("timestamp", System.currentTimeMillis()/1000);
 				 payMap.put("sign", WxSign.createSign(payMap,partnerKey));
//				 	 payMap.put("apiKey", appId);
//					 payMap.put("orderId", partnerId);
//					 payMap.put("mchId", map1.get("prepay_id"));
//					 payMap.put("package", "Sign=WXPay");
//					 payMap.put("nonceStr", nonce_str);
//					 payMap.put("timeStamp", System.currentTimeMillis());
//					 payMap.put("sign", WxSign.createSign(params,partnerKey)); 
 				re.put("data", payMap);
 				return new JsonResult(ResultCode.SUCCESS,"",re);
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
 		}  
		return new JsonResult(ResultCode.SUCCESS,re);
	}
	
	@RequestMapping(value = "cancel_order")
 	@AccessTokenRequired
 	public @ResponseBody Object cancel_order(Long id, Integer pageNo,Integer pageSize,
			HttpServletRequest request, HttpServletResponse response,
			ModelMap model) throws IOException {  
		Order bean = orderService.findById(id);
		if(Order.ORDER_CANCEL.equals(bean.getStatus())){ 
			return new JsonResult(ResultCode.FAIL,"取消失败！",null);
		} 
		bean=orderService.cancel(bean);
		return new JsonResult(ResultCode.SUCCESS,bean);
	}
	
	@RequestMapping(value = "get_order_info")
   	public @ResponseBody Object get_order_info(Long id, Integer pageNo,Integer pageSize,
			HttpServletRequest request, HttpServletResponse response,
			ModelMap model) throws IOException { 
		Order bean = orderService.findById(id);
		if(bean==null||Order.ORDER_CANCEL.equals(bean.getStatus())){
			return new JsonResult(ResultCode.FAIL,"参数错误",null);
		} 
		return new JsonResult(ResultCode.SUCCESS,bean);
	}
	
	@RequestMapping(value = "get_my_order")
 	@AccessTokenRequired
 	public @ResponseBody Object get_my_order(String name,Integer state,Integer pageNo,Integer pageSize,
			HttpServletRequest request, HttpServletResponse response,
			ModelMap model) throws IOException { 
		Pagination pagination = orderService.findFrontPage(name,ApiUtils.getUnifiedUserId(request),state,pageNo,pageSize); 
		List<Order> list=pagination.getDatas();
		for (Order order : list) {
			order.setProductJSON(JSON.parseObject(order.getContent(),JSONObject.class));
		} 
		pagination.setDatas(list);
		return new JsonResult(ResultCode.SUCCESS,pagination);
	}
	
	
	@Autowired
	public StringRedisTemplate strRedisTemplate;
	@Autowired
	private CartService cartService;
	@Autowired
	private AccountService accountService;
	@Autowired
	private OrderService orderService;
	@Autowired
	private ProductService productService;
	@Autowired
	private ProductAttrService productAttrService;
	@Autowired
	private AddressService addressService;
	@Autowired
	private PaylogService payLogService;
	@Autowired
	private PaybillService paybillService;
	@Autowired
	public PaymentsService paymentsService; 
	
}
